<template>
  <div class="super-flow-base-demo">
    <super-flow
      ref="superFlow"
      :node-list="nodeList"
      :link-list="linkList"
      :origin="origin"
      :graph-menu="graphMenuList"
      :node-menu="nodeMenuList"
      :link-menu="linkMenuList"
      :enter-intercept="enterIntercept"
      :output-intercept="outputIntercept"
      :link-desc="linkDesc"
      :style="{ height: `${Math.ceil(this.data.length / 5) * 260}px` }"
    >
      <template v-slot:node="{ meta }">
        <div
          :class="`flow-node flow-node-${meta.prop}`"
          @mousedown="onMouseOver"
        >
          <header class="ellipsis">
            <div class="icon-warpper">
              <el-image
                :src="require('../../assets/images/icon_gear.png')"
                class="icon"
              />
            </div>
          </header>
          <section>
            <div class="name">{{ meta.name }}</div>
            <div class="code">{{ meta.desc }}</div>
          </section>
        </div>
      </template>
    </super-flow>

    <el-dialog
      :title="drawerConf.title"
      :visible.sync="drawerConf.visible"
      :close-on-click-modal="false"
      width="500px"
    >
      <el-form
        @keyup.native.enter="settingSubmit"
        @submit.native.prevent
        v-show="drawerConf.type === drawerType.node"
        ref="nodeSetting"
        :model="nodeSetting"
      >
        <el-form-item label="节点名称" prop="name">
          <el-input
            v-model="nodeSetting.name"
            placeholder="请输入节点名称"
            maxlength="30"
          >
          </el-input>
        </el-form-item>
        <el-form-item label="节点描述" prop="desc">
          <el-input
            v-model="nodeSetting.desc"
            placeholder="请输入节点描述"
            maxlength="30"
          >
          </el-input>
        </el-form-item>
      </el-form>
      <el-form
        @keyup.native.enter="settingSubmit"
        @submit.native.prevent
        v-show="drawerConf.type === drawerType.link"
        ref="linkSetting"
        :model="linkSetting"
      >
        <el-form-item label="连线描述" prop="desc">
          <el-input v-model="linkSetting.desc" placeholder="请输入连线描述">
          </el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button size="mini" @click="drawerConf.cancel"> 取 消 </el-button>
        <el-button size="mini" type="primary" @click="settingSubmit">
          确 定
        </el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
const drawerType = {
  node: 0,
  link: 1,
}

export default {
  props: {
    data: {
      type: Array,
      required: true,
    },
  },
  data() {
    return {
      drawerType,
      drawerConf: {
        title: '',
        visible: false,
        type: null,
        info: null,
        open: (type, info) => {
          const conf = this.drawerConf
          conf.visible = true
          conf.type = type
          conf.info = info
          if (conf.type === drawerType.node) {
            conf.title = '节点'
            if (this.$refs.nodeSetting) this.$refs.nodeSetting.resetFields()
            this.$set(this.nodeSetting, 'name', info.meta.name)
            this.$set(this.nodeSetting, 'desc', info.meta.desc)
          } else {
            conf.title = '连线'
            if (this.$refs.linkSetting) this.$refs.linkSetting.resetFields()
            this.$set(this.linkSetting, 'desc', info.meta ? info.meta.desc : '')
          }
        },
        cancel: () => {
          this.drawerConf.visible = false
          if (this.drawerConf.type === drawerType.node) {
            this.$refs.nodeSetting.clearValidate()
          } else {
            this.$refs.linkSetting.clearValidate()
          }
        },
      },
      linkSetting: {
        desc: '',
      },
      nodeSetting: {
        name: '',
        desc: '',
      },

      origin: [1000, 600],
      nodeList: [],
      linkList: [],
      //模拟数据
      mockData: [
        {
          id: 1,
          code: 'GX20220123001',
          name: '1下料',
          comment: '1111',
        },
        {
          id: 2,
          code: 'GX20220123002',
          name: '2拉直',
          comment: '22222',
        },
        {
          id: 3,
          code: 'GX20220123003',
          name: '3焊接1',
          comment: '3333',
        },
        {
          id: 4,
          code: 'GX20220123004',
          name: '4焊接2',
          comment: '4444',
        },
        {
          id: 5,
          code: 'GX20220123005',
          name: '5焊接3',
          comment: '5555',
        },
        {
          id: 6,
          code: 'GX20220123006',
          name: '6焊接4',
          comment: '6666',
        },
        {
          id: 7,
          code: 'GX20220123007',
          name: '7焊接5',
          comment: '7777',
        },
        {
          id: 8,
          code: 'GX20220123008',
          name: '8焊接5',
          comment: '7777',
        },
        {
          id: 9,
          code: 'GX20220123007',
          name: '9焊接5',
          comment: '7777',
        },
      ],

      graphMenuList: [
        [
          // {
          //   label: '开始节点',
          //   disable(graph) {
          //     return !!graph.nodeList.find((node) => node.meta.prop === 'start')
          //   },
          //   selected: (graph, coordinate) => {
          //     const start = graph.nodeList.find(
          //       (node) => node.meta.prop === 'start',
          //     )
          //     if (!start) {
          //       graph.addNode({
          //         width: 100,
          //         height: 80,
          //         coordinate: coordinate,
          //         meta: {
          //           prop: 'start',
          //           name: '开始节点',
          //         },
          //       })
          //     }
          //   },
          // },
          // {
          //   label: '条件节点',
          //   disable: false,
          //   selected: (graph, coordinate) => {
          //     graph.addNode({
          //       width: 160,
          //       height: 80,
          //       coordinate: coordinate,
          //       meta: {
          //         prop: 'condition',
          //         name: '条件节点',
          //       },
          //     })
          //   },
          // },
          // {
          //   label: '审批节点',
          //   disable: false,
          //   selected: (graph, coordinate) => {
          //     graph.addNode({
          //       width: 160,
          //       height: 80,
          //       coordinate: coordinate,
          //       meta: {
          //         prop: 'approval',
          //         name: '审批节点',
          //       },
          //     })
          //   },
          // },
          // {
          //   label: '工序节点',
          //   disable: false,
          //   selected: (graph, coordinate) => {
          //     graph.addNode({
          //       width: 160,
          //       height: 80,
          //       coordinate: coordinate,
          //       meta: {
          //         prop: 'cc',
          //         name: '工序节点',
          //         desc: '11111',
          //       },
          //     })
          //   },
          // },
          // {
          //   label: '结束节点',
          //   disable(graph) {
          //     return !!graph.nodeList.find((point) => point.meta.prop === 'end')
          //   },
          //   selected: (graph, coordinate) => {
          //     graph.addNode({
          //       width: 80,
          //       height: 50,
          //       coordinate: coordinate,
          //       meta: {
          //         prop: 'end',
          //         name: '结束节点',
          //       },
          //     })
          //   },
          // },
        ],
        [
          // {
          //   label: '打印数据',
          //   selected: (graph, coordinate) => {
          //     console.log(JSON.stringify(graph.toJSON(), null, 2))
          //   },
          // },
          {
            label: '全选',
            selected: (graph, coordinate) => {
              graph.selectAll()
            },
          },
          {
            label: '刷新',
            selected: () => {
              this.initList()
            },
          },
        ],
      ],
      nodeMenuList: [
        // [
        //   {
        //     label: '删除',
        //     disable: false,
        //     hidden(node) {
        //       return node.meta.prop === 'start'
        //     },
        //     selected(node, coordinate) {
        //       node.remove()
        //     },
        //   },
        // ],
        [
          {
            label: '编辑',
            selected: (node, coordinate) => {
              this.drawerConf.open(drawerType.node, node)
            },
          },
        ],
      ],
      linkMenuList: [
        // [
        //   {
        //     label: '删除',
        //     disable: false,
        //     selected: (link, coordinate) => {
        //       link.remove()
        //     },
        //   },
        // ],
        [
          {
            label: '编辑',
            disable: false,
            selected: (link, coordinate) => {
              this.drawerConf.open(drawerType.link, link)
            },
          },
        ],
      ],
    }
  },
  created() {
    console.log('列表', this.data)
    this.initList()
  },
  // mounted() {
  //   this.$nextTick(() => {
  //     this.$el.scrollBy({
  //       left: (this.$el.scrollWidth - this.$el.clientWidth) / 2,
  //       top: (this.$el.scrollHeight - this.$el.clientHeight) / 2,
  //     })
  //   })
  // },
  methods: {
    onMouseOver(graph) {
      // graph.selectAll()
    },
    //根据数据生成列表
    initList() {
      const list = []
      // list.push({
      //   id: 'nodeS3WgFnzCI15X58Qw',
      //   width: 80,
      //   height: 50,
      //   coordinate: [-980, -535],
      //   meta: {
      //     prop: 'start',
      //     name: '工序开始',
      //   },
      // })
      let x, y
      this.data.forEach((item, index) => {
        x = -940 + (index % 5) * 260
        y = -550 + Math.floor(index / 5) * 200
        list.push({
          id: `nodesyxisLH1hJDdPsxx_${index + 1}`,
          width: 220,
          height: 80,
          coordinate: [x, y],
          meta: {
            prop: 'cc',
            name: `工序名称:${item.name}`,
            desc: `工序编码:${item.code}`,
          },
        })
      })
      // list.push({
      //   id: 'nodeDhVU6w2KbEnJCjZs',
      //   width: 80,
      //   height: 50,
      //   coordinate: [x + 220, y + 15],
      //   meta: {
      //     prop: 'end',
      //     name: '工序结束',
      //   },
      // })
      this.nodeList = list
      this.initLink()
    },
    //生成连接线
    initLink() {
      let list = []
      for (let i = 0, l = this.nodeList.length; i < l - 1; i++) {
        list.push({
          id: `link_${i}`,
          startId: this.nodeList[i].id,
          endId: this.nodeList[i + 1].id,
          // startAt: i === 0 ? [100, 40] : [160, 40],
          startAt: [220, 40],
          // endAt: i === l - 1 ? [0, 25] : [0, 40],
          endAt: [0, 40],
          meta: null,
        })
      }
      this.linkList = list
    },
    enterIntercept(formNode, toNode, graph) {
      const formType = formNode.meta.prop
      switch (toNode.meta.prop) {
        case 'start':
          return false
        case 'approval':
          return ['start', 'approval', 'condition', 'cc'].includes(formType)
        case 'condition':
          return ['start', 'approval', 'condition', 'cc'].includes(formType)
        case 'end':
          return ['approval', 'cc'].includes(formType)
        default:
          return true
      }
    },
    outputIntercept(node, graph) {
      return !(node.meta.prop === 'end')
    },
    linkDesc(link) {
      return link.meta ? link.meta.desc : ''
    },
    settingSubmit() {
      const conf = this.drawerConf
      if (this.drawerConf.type === drawerType.node) {
        if (!conf.info.meta) conf.info.meta = {}
        Object.keys(this.nodeSetting).forEach((key) => {
          this.$set(conf.info.meta, key, this.nodeSetting[key])
        })
        this.$refs.nodeSetting.resetFields()
      } else {
        if (!conf.info.meta) conf.info.meta = {}
        Object.keys(this.linkSetting).forEach((key) => {
          this.$set(conf.info.meta, key, this.linkSetting[key])
        })
        this.$refs.linkSetting.resetFields()
      }
      conf.visible = false
    },
  },
}
</script>

<style lang="less">
.ellipsis {
  white-space: nowrap;
  text-overflow: ellipsis;
  overflow: hidden;
  word-wrap: break-word;
}

.super-flow-base-demo {
  width: 100%;
  height: 260px;
  // margin: 0 auto;
  // background-color: #f5f5f5;
  background-color: #fff;
  border: 2px solid #f5f5f5;
  border-radius: 4px;
  overflow: auto;

  .super-flow {
    width: 1600px;
    height: 600px;
  }

  .super-flow__node {
    border-radius: 4px;
    border: px solid #ccc;
    overflow: hidden;
    .flow-node {
      display: flex;
      flex-direction: row;
      justify-content: space-between;
      align-items: center;
      height: 100%;
      > header {
        font-size: 12px;
        width: 26%;
        height: 100%;
        line-height: 32px;
        // padding: 0 10px;
        color: #ffffff;
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        .icon-warpper {
          width: 86%;
          height: 50px;
          background-color: rgb(118, 180, 216);
          display: flex;
          flex-direction: column;
          justify-content: center;
          align-items: center;
          border-radius: 4px;
          .icon {
            width: 32px;
            height: 32px;
          }
        }
      }

      > section {
        flex: 1;
        text-align: center;
        line-height: 20px;
        overflow: hidden;
        // padding: 6px 12px;
        word-break: break-all;
        text-align: left;
        padding-left: 6px;
        .name {
          width: 100%;
          height: 40px;
          // background-color: red;
          line-height: 40px;
          font-size: 14px;
        }
        .code {
          width: 100%;
          height: 40px;
          line-height: 30px;
          font-size: 12px;
        }
      }

      &.flow-node-start {
        > header {
          // background-color: #55abfc;
          height: 50px;
          line-height: 50px;
          background-color: rgb(0, 0, 0);
          text-align: center;
        }
      }

      &.flow-node-condition {
        > header {
          background-color: #bc1d16;
        }
      }

      &.flow-node-approval {
        > header {
          background-color: rgba(188, 181, 58, 0.76);
        }
      }

      &.flow-node-cc {
        > header {
          // background-color: #30b95c;
          background-color: #f4f4f4;
        }
      }

      &.flow-node-gx {
        > header {
          background-color: #98a09a;
        }
      }

      &.flow-node-end {
        > header {
          height: 50px;
          line-height: 50px;
          background-color: rgb(0, 0, 0);
          text-align: center;
        }
      }
    }
  }
}
</style>
